package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.entity.ParameterModel;
import com.ciei.dpagm.entity.ParameterModule;
import com.ciei.dpagm.entity.Users;
import com.ciei.dpagm.mapper.ParameterModuleMapper;
import com.ciei.dpagm.util.APP;
import com.ciei.dpagm.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ParameterModuleService extends BaseService<ParameterModuleMapper, ParameterModule> implements IModuleService {

    @Autowired
    private ParameterService parameterService;

    @Autowired
    private RuleSetParameterModuleService ruleSetParameterModuleService;

    /**
     * 根据名称搜索模块列表
     * @param searchName
     * @return
     */
    public List<ParameterModule> searchListByName(String searchName){
        if (StringUtils.isNotBlank(searchName)){
            QueryWrapper<ParameterModule> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().like(ParameterModule::getPropertyName,searchName);
            return list(queryWrapper);
        }
        return list();
    }


    /**
     * 组装参数库模块列表
     * @param moduleList
     * @return
     */
    public JSONArray packageDataList(List<ParameterModule> moduleList){
        JSONArray jsonArray = new JSONArray();
        for (ParameterModule parameterModule : moduleList){
            JSONObject jsonData = new JSONObject();
            jsonData.put("id",parameterModule.getModuleId());
            jsonData.put("pid",parameterModule.getParameterModelId());
            jsonData.put("propertyName",parameterModule.getPropertyName());
            jsonArray.add(jsonData);
        }
        return jsonArray;
    }

    /**
     * 加载参数库模块列表
     * @param parameterModelId 参数模型ID
     * @return
     */
    @Override
    public JSONObject loadModuleList(Integer parameterModelId){
        List<ParameterModule> moduleList = findByProperty(ParameterModule::getParameterModelId,parameterModelId);
        return JsonUtil.getSuccess("").fluentPut(APP.DATA, packageDataList(moduleList));
    }

    /**
     * json数据转成实体
     * @param data  Json数据
     * @return
     */
    public ParameterModule jsonToPojo(JSONObject data){
        ParameterModule parameterModule = new ParameterModule();
        parameterModule.setParameterModelId(data.getInteger("pid"));
        parameterModule.setPropertyName(data.getString("propertyName"));
        return parameterModule;
    }

    /**
     * 根据模型ID和中文名称查询列表
     * @param parameterModelId
     * @param propertyName
     * @return
     */
    public List<ParameterModule> getListByModelIdAndPropertyName(Integer parameterModelId,String propertyName){
        return findByProperties(new String[]{"parameterModelId","propertyName"},new Object[]{parameterModelId,propertyName});
    }

    /**
     * 根据模型ID和英文名称查询列表
     * @param parameterModelId
     * @param propertyKey
     * @return
     */
    public List<ParameterModule> getListByModelIdAndPropertyKey(Integer parameterModelId,String propertyKey){
        return findByProperties(new String[]{"parameterModelId","propertyKey"},new Object[]{parameterModelId,propertyKey});
    }

    /**
     * 根据模型ID查询列表
     * @param parameterModelId
     * @return
     */
    public List<ParameterModule> getListByModelId(Integer parameterModelId){
        return findByProperty(ParameterModule::getParameterModelId,parameterModelId);
    }

    /**
     * 通过模型ID批量复制模块数据
     * @param fromParameterModelId
     * @param toParameterModelId
     * @return
     */
    public  List<ParameterModule> copyDataThroughModelId(Integer fromParameterModelId,Integer toParameterModelId){
        List<ParameterModule> fromParameterModuleList = getListByModelId(fromParameterModelId);
        List<ParameterModule> toParameterModuleList = new ArrayList<>();
        if (!fromParameterModuleList.isEmpty()){
            for (ParameterModule fromParameterModule : fromParameterModuleList){
                ParameterModule toParameterModule = new ParameterModule();
                toParameterModule.setParameterModelId(toParameterModelId);
                toParameterModule.setPropertyName(fromParameterModule.getPropertyName());
                toParameterModuleList.add(toParameterModule);
            }
            insertBatch(toParameterModuleList);
            parameterService.copyDataThroughModuleList(fromParameterModuleList,toParameterModuleList);
        }
        return toParameterModuleList;
    }

    /**
     * 添加模块
     * @param data
     * @return
     */
    @Override
    public JSONObject add(JSONObject data){
        JSONObject validateResult = validateModuleData(data);
        if (!validateResult.getBoolean(APP.SUCCESS)){
            return validateResult;
        }
        ParameterModule parameterModule = jsonToPojo(data);
        save(parameterModule);
        return init(parameterModule);
    }

    /**
     * 初始化
     * @param parameterModule
     * @return
     */
    public JSONObject init(ParameterModule parameterModule){
        JSONObject data = new JSONObject();
        data.fluentPut("id",parameterModule.getModuleId())
                .fluentPut("propertyName",parameterModule.getPropertyName() == null ? "" : parameterModule.getPropertyName())
                .fluentPut("pid",parameterModule.getParameterModelId());
        return JsonUtil.getSuccess("").fluentPut(APP.DATA,data);
    }

    /**
     * 修改模块
     * @param data
     * @return
     */
    @Override
    public JSONObject update(JSONObject data){
        JSONObject validateResult = validateModuleData(data);
        if (!validateResult.getBoolean(APP.SUCCESS)){
            return validateResult;
        }
        ParameterModule parameterModule = jsonToPojo(data);
        parameterModule.setModuleId(data.getInteger("id"));
        updateById(parameterModule);
        return init(parameterModule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject delete(JSONObject data) {
        Integer moduleId = data.getInteger("id");
        ParameterModule parameterModule = findById(moduleId);
        if (parameterModule != null){
            //如果模块被引用
            if (ruleSetParameterModuleService.isReferenced(Arrays.asList(moduleId))){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY,"该模块被引用,不可删除!");
            }
            parameterService.deleteByModuleId(moduleId);
            removeById(moduleId);
        }
        return JsonUtil.getSuccess("");
    }

    public JSONObject deleteByModelId(Integer parameterModelId) {
        List<ParameterModule> parameterModuleList = getListByModelId(parameterModelId);
        if (!parameterModuleList.isEmpty()){
            //如果模块被引用
            if (ruleSetParameterModuleService.isReferenced(parameterModuleList.stream().map(ParameterModule::getModuleId).collect(Collectors.toList()))){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY,"该参数库存在被引用模块,不可删除!");
            }
            parameterService.deleteByModelId(parameterModelId);
            removeByIds(parameterModuleList.stream().map(ParameterModule::getModuleId).collect(Collectors.toList()));
        }
        return JsonUtil.getSuccess("");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject copy(JSONObject data, Users user) {
        data.put("copy","copy");
        JSONObject validateResult = validateModuleData(data);
        if (!validateResult.getBoolean(APP.SUCCESS)){
            return validateResult;
        }
        ParameterModule parameterModule = jsonToPojo(data);
        save(parameterModule);
        parameterService.copyDataThroughModuleId(data.getInteger("id"),parameterModule.getModuleId());
        return init(parameterModule);
    }

    /**
     * 校验数据
     * @param data
     * @return
     */
    public JSONObject validateModuleData(JSONObject data){
        String propertyName = data.getString("propertyName");
        if (StringUtils.isBlank(propertyName)){
            return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM);
        }
        Integer moduleId = data.getInteger("id");
        Integer pid = data.getInteger("pid");
        if (moduleId == null || StringUtils.isNotBlank(data.getString("copy"))){
            if (!getListByModelIdAndPropertyName(pid,propertyName).isEmpty()){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"名称重复,请重新输入!");
            }
        }else {
            ParameterModule oldParameterModule = findById(moduleId);
            if (oldParameterModule == null){
                return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND);
            }
            if (!getListByModelIdAndPropertyName(pid,propertyName).isEmpty() && !oldParameterModule.getPropertyName().equals(propertyName)){
                return JsonUtil.getFail(ErrorCodeEnum.DUPLICATE_DATA,"名称重复,请重新输入!");
            }
        }
        return JsonUtil.getSuccess("");
    }

    @Override
    public JSONObject export(JSONObject data, HttpServletResponse response) {
        return parameterService.exportByModuleId(data.getInteger("id"),response);
    }

    /**
     * 根据模型ID列表查询列表
     * @param parameterModelIdList
     * @return
     */
    public List<ParameterModule> getListByModelIdList(List<Integer> parameterModelIdList){
        if(parameterModelIdList.isEmpty()){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ParameterModule> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ParameterModule::getParameterModelId,parameterModelIdList);
        return list(lambdaQueryWrapper);
    }

}
